package com.mattgarner.jaddas.node.command.state;

import com.mattgarner.jaddas.common.ResultSet;
import com.mattgarner.jaddas.common.ResultSetException;
import com.mattgarner.jaddas.common.ResultSetHeader;
import com.mattgarner.jaddas.dataset.DataSet;
import com.mattgarner.jaddas.node.DataSetManager;
import com.mattgarner.jaddas.node.RemoteClient;
import com.mattgarner.jaddas.node.command.CommandParser;
import com.mattgarner.jaddas.node.data.LocalTableDataProvider;
import com.mattgarner.jaddas.node.net.Protocol;
import com.mattgarner.jaddas.node.net.Worker;

public class CmdShow extends CommandParser {

	public CmdShow(Worker serverWorker, RemoteClient client) {
		super(serverWorker, client);
	}
	
	// SHOW
	public final boolean parseCommand(String command) {
		Worker worker = getServerWorker();
		RemoteClient clientConfig = getRemoteClient();
		
		String[] cmd = extractRegexGroups("^SHOW\\s+(.*?)$", command.toUpperCase());
		if(cmd[0].toUpperCase().matches("CLIENTS")) {					
			// create ResultSet
			try { 
				ResultSetHeader rsHeader = new ResultSetHeader(clientConfig.getStringEncoding());
				rsHeader.addIntColumn("ID");
				rsHeader.addStringColumn("Type");
				rsHeader.addStringColumn("Host");
				rsHeader.addStringColumn("Last Activity");
				
				ResultSet resultSet = new ResultSet(rsHeader);
				
				RemoteClient[] remoteClients = stateManager.getRemoteClients();
				for(int a=0; a<remoteClients.length; a++) {
					resultSet.setValue(a, 0, remoteClients[a].getClientID());
					if(remoteClients[a].getClientType() == 0) {
						resultSet.setValue(a, 1, "CLIENT");
					} else {
						resultSet.setValue(a, 1, "NODE");
					}
					resultSet.setValue(a, 2, remoteClients[a].getIPAddressString());
					
					resultSet.setValue(a, 3, ((System.currentTimeMillis() - remoteClients[a].getLastActivityTime())/1000) + " sec");
					
					//Date date = new Date(remoteClients[a].getLastActivityTime());
					//resultSet.setValue(a, 3, date.toString());
				}
				sendResultSet(resultSet);
				return true;
			} catch (ResultSetException e) {
				// shouldn't happen
			}
			
		}
		
		if(cmd[0].toUpperCase().matches("DATASETS")) {
			// create ResultSet
			try { 
				ResultSetHeader rsHeader = new ResultSetHeader(clientConfig.getStringEncoding());
				rsHeader.addIntColumn("ID");
				rsHeader.addStringColumn("Name");
				rsHeader.addStringColumn("Description");
				rsHeader.addIntColumn("Partition Max Tuples");
				rsHeader.addIntColumn("Partition Count");
				rsHeader.addIntColumn("Serial");
				
				ResultSet resultSet = new ResultSet(rsHeader);
				
				DataSetManager dsManager = DataSetManager.getInstance();
				DataSet[] onlineDataSets = dsManager.getOnlineDataSets();
				
				for(int a=0; a<onlineDataSets.length;a++) {
					resultSet.setValue(a, 0, onlineDataSets[a].getID());
					resultSet.setValue(a, 1, onlineDataSets[a].getName());
					resultSet.setValue(a, 2, onlineDataSets[a].getDescription());
					resultSet.setValue(a, 3, onlineDataSets[a].getPartitionMaxTupleCount());
					resultSet.setValue(a, 4, onlineDataSets[a].getCurrentPartitionID());
					resultSet.setValue(a, 5, onlineDataSets[a].getSerialNumber());
				}
				
				sendResultSet(resultSet);
				return true;
			} catch (ResultSetException e) {
				worker.sendMessage(Protocol.MSG_NAK, "ResultSet creation error: " + e.getMessage());
				return true;
			}
		}
		
		if(cmd[0].toUpperCase().contains("INDEX")) {
			String[] subCmd = extractRegexGroups("(?i)^SHOW\\s+INDEX\\s+ON\\s+(.+?)\\s*$", command);
			String dsName = subCmd[0];
			if(dsName != null) {
				DataSetManager dsManager = DataSetManager.getInstance();
				DataSet dataSet = dsManager.getDataSetByName(dsName);
				
				if(dataSet == null) {
					worker.sendMessage(Protocol.MSG_NAK, "Dataset '" + dsName + "' does not exist.");
					return true;
				}
				
				// run stats and return results
				try {
					LocalTableDataProvider dsDataProvider = new LocalTableDataProvider(dataSet);
					sendResultSet(dsDataProvider.getIndexStatisticsResultSet(clientConfig.getStringEncoding()));
					return true;
				} catch(Exception e) {
					worker.sendMessage(Protocol.MSG_NAK, "Exception: " + e.getMessage());
					return true;
				}

			}
			
		}

		return false;
	}

}
